<?php
namespace App\Common\Lib\Fun;

use App\Common as com;

class Model {
	/**
	 * 数据复用检测，如复用数据不符合，则从数据库读取
	 * @param Model $model 初始化的模型对象（必须已实例化，且已传入查询参数）
	 * @param array $reuse_data 复用的数据
	 * @param array $need_field 需要的字段（注："*"会被省略检测）
	 * @return array 符合的数据
	 * @throws
	 */
	public static function reuseFind( \think\db\Query $model, $reuse_data = [], $need_field = [ '*' ] ){
		//检测预读取数据是否符合
		if( ! empty( $reuse_data ) ){
			//检测所需字段是否都存在
			$need_field_match = 1;
			foreach ( $need_field as $need_field_value ){
				if( $need_field_value == '*' ) continue; //不检测*字段
				if( ! array_key_exists( $need_field_value, $reuse_data ) ){
					$need_field_match = 0;
					break;
				}
			}
			//
			if( $need_field_match ) return $reuse_data;
		}
		//从数据库获取数据
		$data = $model->field( implode( $need_field, ',' ) )->find();
		return is_object( $data ) ? $data->toArray() : $data;
	}

	/**
	 * 模型对象转数组（自动判断是单一对象还是多组对象）
	 * @param object $model_res 模型返回的数据
	 * @return array 转换结果（无法转换时抛出异常）
	 */
	public static function toArray( $model_res ){
		if( is_object( $model_res ) ){
			return self::toArrayOfFind( $model_res );
		}else if( is_object( $model_res[0] ?? NULL ) ){
			return self::toArrayOfSelect( $model_res );
		}else if( is_array( $model_res ) ){
			return $model_res;
		}else if( $model_res == null ){
			return [];
		}else{
			throw com\Lib\Err\Exception::makeOfNew( '', com\Lib\Err\Code::$sysDataError );
		}
	}
	
	/**
	 * 模型对象转数组->单一对象
	 * @param object $model_res 模型返回的数据->单一对象
	 * @return array 转换结果（无法转换时抛出异常）
	 */
	public static function toArrayOfFind( $model_res ){
		if( is_array( $model_res ) ) return $model_res;
		if( method_exists( $model_res, 'toArray' ) ){
			return $model_res->toArray();
		}else{
			throw com\Lib\Err\Exception::makeOfNew( '', com\Lib\Err\Code::$sysDataError );
		}
	}
	/**
	 * 模型对象转数组->多组对象
	 * @param object $model_res 模型返回的数据->多组对象
	 * @return array 转换结果（无法转换时抛出异常）
	 */
	public static function toArrayOfSelect( $model_res ){
		if( is_array( $model_res ) && is_array( $model_res[0] ) ) return $model_res;
		if( ! is_array( $model_res ) || ! is_object( $model_res[0] ) ) throw com\Lib\Err\Exception::makeOfNew( '', com\Lib\Err\Code::$sysDataError );;
		foreach ( $model_res as &$model_res_value ){
			$model_res_value = self::toArrayOfFind( $model_res_value, [] );
		}
		return $model_res;
	}
	
	/**
	 * 获取 model::create 返回的主键，如果不存在则返回异常
	 * @param unknown $create_return_model model::create 返回的对象
	 * @param string $pk 主键名（默认：id）
	 * @return int [0]不存在 [>0]主键值
	 */
	public static function getCreatePkOrFail( $create_return_model, $pk = 'id' ){
		$pk = self::getCreatePk( $create_return_model, $pk );
		if( $pk> 0 ){
			return $pk;
		}else{
			throw com\Lib\Err\Exception::makeOfNew( '', com\Lib\Err\Code::$sysDataError );
		}
	}
	
	/**
	 * 获取 model::create 返回的主键
	 * @param unknown $create_return_model model::create 返回的对象
	 * @param string $pk 主键名（默认：id）
	 * @return int [0]不存在 [>0]主键值
	 */
	public static function getCreatePk( $create_return_model, $pk = 'id' ){
		if ( is_subclass_of($create_return_model, 'think\Model' ) ) {
			$model_get_data = $create_return_model->getData();
			if( array_key_exists( 'id', $model_get_data ) ){
				return $model_get_data[ $pk ] ?? 0;
			}
		}
		return 0;
	}
}
